/// 验证 SchemeManager 依赖注入解决方案的测试
/// 
/// 这个测试文件演示了如何在依赖注入框架中使用修改后的 SchemeManager
use std::sync::Arc;
use anyhow::Result;

use crate::extension::index::scheme_manager::SchemeManager;
use crate::di::app_container::AppContainer;
use crate::config::app_error::AppResult;

/// 简单的测试函数，验证 SchemeManager 的基本功能
pub async fn test_scheme_manager_basic_functionality() -> Result<()> {
    println!("🧪 开始测试 SchemeManager 基本功能...");
    
    // 创建 SchemeManager 实例
    let scheme_manager = SchemeManager::new();
    
    // 测试初始状态
    let initial_size = scheme_manager.size()?;
    println!("✅ 初始 schemes 数量: {}", initial_size);
    assert_eq!(initial_size, 0);
    
    // 测试获取所有 schemes
    let schemes = scheme_manager.schemes()?;
    println!("✅ 获取所有 schemes 成功，数量: {}", schemes.len());
    assert_eq!(schemes.len(), 0);
    
    println!("🎉 SchemeManager 基本功能测试通过！");
    Ok(())
}

/// 测试 Arc<SchemeManager> 的使用
pub async fn test_arc_scheme_manager() -> Result<()> {
    println!("🧪 开始测试 Arc<SchemeManager> 使用...");
    
    // 创建 Arc<SchemeManager>，模拟依赖注入框架返回的情况
    let scheme_manager = Arc::new(SchemeManager::new());
    
    // 测试在 Arc 中使用 SchemeManager 的方法
    let size = scheme_manager.size()?;
    println!("✅ 通过 Arc 获取 size: {}", size);
    
    let schemes = scheme_manager.schemes()?;
    println!("✅ 通过 Arc 获取 schemes: {} 个", schemes.len());
    
    // 测试多个 Arc 引用
    let scheme_manager_clone = Arc::clone(&scheme_manager);
    let size_clone = scheme_manager_clone.size()?;
    println!("✅ 通过克隆的 Arc 获取 size: {}", size_clone);
    
    assert_eq!(size, size_clone);
    
    println!("🎉 Arc<SchemeManager> 使用测试通过！");
    Ok(())
}

/// 测试并发访问
pub async fn test_concurrent_access() -> Result<()> {
    println!("🧪 开始测试并发访问...");
    
    let scheme_manager = Arc::new(SchemeManager::new());
    let mut handles = vec![];
    
    // 创建多个并发任务
    for i in 0..5 {
        let manager = Arc::clone(&scheme_manager);
        let handle = tokio::spawn(async move {
            // 每个任务都尝试读取 schemes
            let size = manager.size().unwrap();
            let schemes = manager.schemes().unwrap();
            println!("  📊 任务 {} - size: {}, schemes: {}", i, size, schemes.len());
            Ok::<(), anyhow::Error>(())
        });
        handles.push(handle);
    }
    
    // 等待所有任务完成
    for handle in handles {
        handle.await??;
    }
    
    println!("🎉 并发访问测试通过！");
    Ok(())
}

/// 演示解决方案的主要优势
pub async fn demonstrate_solution_benefits() -> Result<()> {
    println!("\n🌟 演示解决方案的主要优势:");
    
    // 1. 从依赖注入容器获取服务（模拟）
    println!("1️⃣ 从依赖注入容器获取 SchemeManager:");
    let scheme_manager: Arc<SchemeManager> = Arc::new(SchemeManager::new());
    println!("   ✅ 成功获取 Arc<SchemeManager>");
    
    // 2. 直接调用方法，无需可变引用
    println!("2️⃣ 直接调用方法，无需可变引用:");
    let size = scheme_manager.size()?;
    println!("   ✅ 调用 size() 方法成功: {}", size);
    
    let schemes = scheme_manager.schemes()?;
    println!("   ✅ 调用 schemes() 方法成功: {} 个", schemes.len());
    
    // 3. 线程安全的并发访问
    println!("3️⃣ 线程安全的并发访问:");
    test_concurrent_access().await?;
    
    // 4. 内存效率
    println!("4️⃣ 内存效率:");
    let manager1 = Arc::clone(&scheme_manager);
    let manager2 = Arc::clone(&scheme_manager);
    println!("   ✅ 多个 Arc 引用共享同一个实例");
    println!("   ✅ Arc 强引用计数: {}", Arc::strong_count(&scheme_manager));
    
    // 释放引用
    drop(manager1);
    drop(manager2);
    println!("   ✅ 释放引用后计数: {}", Arc::strong_count(&scheme_manager));
    
    println!("\n🎉 所有优势演示完成！");
    Ok(())
}

/// 运行所有测试
pub async fn run_all_tests() -> Result<()> {
    println!("🚀 开始运行 SchemeManager 解决方案测试套件");
    println!("{}", "=".repeat(60));
    
    test_scheme_manager_basic_functionality().await?;
    println!();
    
    test_arc_scheme_manager().await?;
    println!();
    
    test_concurrent_access().await?;
    println!();
    
    demonstrate_solution_benefits().await?;
    
    println!("{}", "=".repeat(60));
    println!("🎉 所有测试通过！SchemeManager 依赖注入解决方案工作正常！");
    
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_scheme_manager_solution() {
        run_all_tests().await.expect("测试应该通过");
    }
}
